
#include "graphics/particlesystem.h"
#include "graphics/graphicsmanager.h"
#include "graphics/materialmanager.h"
#include "graphics/texturemanager.h"
#include "graphics/renderer.h"
#include "graphics/particleemitter.h"

namespace dw
{
	namespace graphics
	{

		ParticleSystem::ParticleSystem()
		{
			srand((unsigned int)0);
		}

		ParticleSystem::~ParticleSystem()
		{
			std::vector< IParticleEmitter * >::iterator it;
//			vector< IParticleDeflector * >::iterator it;

			for (it = _emitters.begin(); it != _emitters.end(); ++it)
				delete (*it);
			_emitters.clear();
		}

		void ParticleSystem::update(const float& dt)
		{
			std::vector< IParticleEmitter * >::iterator it;

			for (it = _emitters.begin(); it != _emitters.end(); ++it)
				(*it)->update(dt);
		}

		bool ParticleSystem::addEmitter(IParticleEmitter * emitter)
		{
			std::vector< IParticleEmitter * >::const_iterator it;

			if (!emitter)
				return false;

			for (it = _emitters.begin(); it != _emitters.end(); ++it)
				if ((*it)->getName() == emitter->getName())
					return false;

			_emitters.push_back(emitter);
			
			return true;
		}

		void ParticleSystem::render(Renderer* renderer) const
		{
			float quadratic[] =  { 0.0f, 0.0f, 0.004f };
			glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic);

			float maxSize;
			glGetFloatv(GL_POINT_SIZE_MAX_ARB, &maxSize);

			renderer->setRenderState(Renderer::RS_DEPTH_TEST, true);
			glDepthMask(GL_FALSE);
			renderer->setRenderState(Renderer::RS_BLENDING, true);
			renderer->setRenderState(Renderer::RS_BLEND_SRC_FUNC, Renderer::BlendMode::SRC_ALPHA);
			renderer->setRenderState(Renderer::RS_BLEND_DST_FUNC, Renderer::BlendMode::ONE);

			//glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f);

			glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 1.0f);

			glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, 1000.f);

			glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
			
			std::vector< IParticleEmitter * >::const_iterator it;

			for (it = _emitters.begin(); it != _emitters.end(); ++it)
				(*it)->render();

			renderer->setRenderState(Renderer::RS_DEPTH_TEST, true);
			renderer->setRenderState(Renderer::RS_BLENDING, false);
			glDepthMask(GL_TRUE);

			//renderer->setVertexBuffer(_vertexBuffer);
			//renderer->setMaterial(MaterialManager::instance().getMaterial(_materialName));
		}

	}
}